<HEAD>
  <SCRIPT SRC="../ganja.js"></SCRIPT>
</HEAD>
<BODY><SCRIPT>
// Create a Clifford Algebra with 3,0,1 metric. 
Algebra(3,0,1,()=>{ 

  // We store position/orientation and linear/angular momentum in a single bivector.
  // In this example, we assume a symmetric object so we can ignore the inertia tensor. 
  // Note that velocity (both linear and angular) and momentum (idem) are each others dual.
 
  // Helper : points and RK4 integrator.
  var point = (x,y,z)=>!(1e0+x*1e1+y*1e2+z*1e3),
      RK4 = (f,y,h)=>{ var k1=f(y), k2=f(y+0.5*h*k1), k3=f(y+0.5*h*k2), k4=f(y+h*k3); return  y+(h/3)*(k2+k3+(k1+k4)*0.5); };

  // Our box definition, its vertices in Body and Space coordinates, its edges.
  var mass  = 1, size  = [1,1,1],
      cubeB = [...Array(8)].map((x,i)=>point.apply(this,size.map((s,j)=>s*(((i>>j)%2)-0.5)))),
      cubeF = [[0,1,2],[1,2,3],[4,5,6],[5,6,7],[0,1,4],[4,5,1],[2,6,7],[2,3,7],[0,4,2],[4,2,6],[1,5,7],[1,3,7]].map(x=>x.map(i=>cubeB[i])),
      cube  = {data:cubeF, transform:1+0e1};

  // our physics state. 
  var State  = [ 1,                   // The starting position and orientation in space. (identity) 
                 0.35e13-.27e12],     // The starting linear and rotational velocity in body.
      dState = ([g,v])=>[             // given g, the current pos/rot in space, and v the velocity in the body,
                 g*v,                 // Convert velocity from body to space. (will update space pos/rot)
                 !(!v*v-v*!v)         // momentum and velocity are dual, commutator gives derivative.
                ];

  // Graph the 3D items
  document.body.appendChild(this.graph(()=>{
  // Advance the state one time step of 0.05 and renormalize.  
    State = RK4(dState,State,0.05);
    State[0] = State[0].Normalized;
  // Set object transformation.
    cube.transform = State[0];
  // Render the cube
    return [0xFFCC44,cube];
  },{animate:true,gl:true}));
  
});
</SCRIPT></BODY>